package com.javaear.beangenerator.processor;

import com.javaear.beangenerator.Beaner;
import com.javaear.beangenerator.Context;
import com.javaear.beangenerator.Fielder;
import com.javaear.beangenerator.support.json.JsonObject;
import com.javaear.beangenerator.tools.Assert;
import com.javaear.beangenerator.tools.StringUtils;

import java.util.*;

/**
 * json processor
 *
 * @author aooer
 */
public class JsonReverseProcessor extends AbstractProcessor {

    /**
     * json source string
     */
    private String jsonStr;

    /**
     * parent beanName
     */
    private String beanName;

    public void init(Context context) {
        Assert.notNull(jsonStr = context.getString("json_param"));
        Assert.notNull(beanName = context.getString("json_beanName"));
    }

    public Beaner process() {
        return loopProces((LinkedHashMap<?, ?>) new JsonObject(jsonStr).getJsonObj(), beanName);
    }

    /**
     * loop the linkedHashMap
     * find child type
     * do case process
     *
     * @param jsonObj  jsonObj
     * @param beanName beanName
     * @return Beaner
     */
    private Beaner loopProces(LinkedHashMap<?, ?> jsonObj, String beanName) {
        List<Fielder> fielderList = new ArrayList<Fielder>();
        List<Beaner> children = new ArrayList<Beaner>();
        for (Map.Entry<?, ?> e : jsonObj.entrySet()) {
            String key = StringUtils.upperCaseFirstChar((String) e.getKey());
            Object value = e.getValue();
            if (value instanceof ArrayList) {
                if (((Collection<?>) value).isEmpty()) {
                    fielderList.add(new Fielder((String) e.getKey(), "List"));
                } else {
                    Object fieldFirst = ((ArrayList) value).get(0);
                    String fieldType = fieldFirst.getClass().getSimpleName();
                    if (fieldFirst instanceof ArrayList)
                        fieldType = "List";
                    if (fieldFirst instanceof LinkedHashMap)
                        fieldType = key;
                    fielderList.add(new Fielder((String) e.getKey(), "List<".concat(fieldType).concat(">")));
                    if (fieldFirst instanceof LinkedHashMap)
                        children.add(loopProces((LinkedHashMap<?, ?>) fieldFirst, key));
                    if (fieldFirst instanceof ArrayList)
                        children.add(loopProces((LinkedHashMap<?, ?>) ((ArrayList) fieldFirst).get(0), key));
                }
            } else if (value instanceof LinkedHashMap) {
                fielderList.add(new Fielder((String) e.getKey(), (String) e.getKey()));
                children.add(loopProces((LinkedHashMap<?, ?>) value, (String) e.getKey()));
            } else {
                fielderList.add(new Fielder((String) e.getKey(), value.getClass().getSimpleName()));
            }
        }
        return new Beaner(beanName, fielderList, children);
    }

}
